#include<bits/stdc++.h>
using namespace std;
#define N 1000010
typedef long long LL;

struct edge{
    int to, nxt, val;
}e[N << 1];
int head[N], c[N], deg[N], n, len, q[N << 1];
LL dis[N], f[N], ans;
bool vis[N];

void add_edge(int u, int v, int w){
    e[++len].to = v; e[len].val = w; e[len].nxt = head[u];  head[u] = len; deg[v]++; return ;
}

void init(){
    len = 0;
    scanf("%d", &n);
    for(int u = 1; u <= n; u++){
        int v, w;
        scanf("%d%d", &v, &w);
        add_edge(u, v, w); add_edge(v, u, w);
    }
    return ;
}

void bfs(int cur, int num){
    queue<int> Q;
    Q.push(cur); c[cur] = num;
    while(!Q.empty()){
        cur = Q.front(); Q.pop();
        for(int i = head[cur]; i; i = e[i].nxt){
            int to = e[i].to;
            if(!c[to]) Q.push(to), c[to] = num;
        }
    }
    return ;
}

void topsort(){
    queue<int> Q;
    for(int i = 1; i <= n; i++) if(deg[i] == 1) Q.push(i);
    while(!Q.empty()){
        int cur = Q.front(); Q.pop();
        for(int i = head[cur]; i; i = e[i].nxt){
            int to = e[i].to;
            if(deg[to] > 1){
                dis[c[cur]] = max(dis[c[cur]], f[cur] + f[to] + e[i].val);
                f[to] = max(f[to], f[cur] + e[i].val);
                if(--deg[to] == 1) Q.push(to);
            }
        }
    }
    return ;
}

LL a[N << 1], b[N << 1];

void dp(int cur, int num){
    int m = 0, y = cur, i, z = 0;
    do{
        a[++m] = f[y];
        deg[y] = 1;
        for(i = head[y]; i; i = e[i].nxt){
            if(deg[e[i].to] > 1){
                b[m + 1] = b[m] + e[i].val;
                y = e[i].to;
                break;
            }
        }
    } while(i);
    if(m == 2){
        // 二元环无法确定回到cur的边是来时的那一条还是另外一条，所以索性单独处理
        for(i = head[y]; i; i = e[i].nxt){
            if(e[i].to == cur) z = max(z, e[i].val);
        }
        dis[num] = max(dis[num], f[cur] + f[y] + z);
        return ;
    }
    // 而对于大于二元环的，可以确定恰好是m条边，不重复也不遗漏。
    for(i = head[y]; i; i = e[i].nxt){
        if(e[i].to == cur){
            b[m + 1] = b[m] + e[i].val;
            break;
        }
    }
    // 把环拆开倍长
    for (int i = 1; i < m; i++) {
		a[m+i] = a[i];
		b[m+i] = b[m+1] + b[i];
	}
    // 单调队列优化DP
    deque<int > Q;
    Q.push_front(1);
	for (int i = 2; i < (m << 1); i++) {
        if(!Q.empty() && i - Q.front() >= m) Q.pop_front();
        dis[num] = max(dis[num], a[i] + a[Q.front()] + b[i] - b[Q.front()]);
        while(!Q.empty() && a[Q.back()] - b[Q.back()] <= a[i] - b[i]) Q.pop_back();
        Q.push_back(i);
	}
    return ;
}

void solve(){
    LL ans = 0; int cnum = 0;
    // 拉出每一棵基环树
    for(int i = 1; i <= n; i++){
        if(!c[i]) bfs(i, ++cnum);
    }
    topsort(); // 拓扑排序处理环外的枝桠（子树）
    for(int i = 1; i <= n; i++){
        if(deg[i] > 1 && !vis[c[i]]){
            vis[c[i]] = true;
            dp(i, c[i]);
            ans += dis[c[i]];
        }
    }
    printf("%lld\n", ans);
    return ;
}
int main(){
    init();
    solve();
    return 0;
}